home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / genmix1b.zip / GENMIX / README.TXT
Text File  |  1995-04-15  |  23KB  |  547 lines

  1. Thanks for requesting information about Genmix!  And, thanks for being
  2. patient while I got this stuff together.  The first beta will be relased
  3. next week, and another message will be sent to this list telling ya where
  4. to download it (on compuserve and the internet).  Here's the release notes
  5. for the first beta, they should answer most of your questions.  If you have
  6. any questions not covered in these notes, please mail them to me, and I'll
  7. add what answers I can to the first distribution.
  8.  
  9.         -Ian
  10.  
  11. ---------------------------------------------------------------------------
  12.  
  13. GENMIX BETA 1 RELEASE NOTES
  14.  
  15. WHAT IS GENMIX
  16. --------------
  17. Genmix is a C code library that you can add to your MS Windows or Macintosh
  18. applications.  Genmix provides real-time additive waveform synthesis and 
  19. output -- it mixes and plays sounds.  A 17-function API (Application Program 
  20. Interface) allows full control over the sound mixing process.
  21.  
  22.  
  23. BETA NOTICE
  24. -----------
  25. This software is currently not ready to be incorporated in commercial 
  26. applications.  There are problems both with the generic mixer code, and with
  27. the implementations of wave i/o.  See the section "current problems" for
  28. more information.  So, use this code AT YOUR OWN RISK.
  29.  
  30. Genmix will remain in beta until it is stable and runs well on 95% installed
  31. Macintosh and MPC2 base.  There will always be a few percent with obsolete
  32. or unsupported operating systems, hardware, or software audio drivers.
  33. Sound quality should be as good as possible on systems supported.
  34.  
  35. Beta is expected to end shortly _after_ Windows 95 ships, in 4Q95.  Expect
  36. probably four or five beta releases.
  37.  
  38.  
  39. LICENSE AGREEMENT
  40. -----------------
  41. Genmix is (c) Copyright 1995 Ian A. McLean.  All rights are reserved except
  42. as described in the following four items:
  43.  
  44. 1.    You may redistribute the ZIP file containing this 
  45.       file, but only in its original, unmodified form.
  46.       No fee may be charged.
  47. 2.    You may NOT distribute any application derived from 
  48.       any portion of the Genmix source code without express 
  49.       written permission from Ian A. McLean.
  50. 3.    You may create works derived from the Genmix source 
  51.       code only if they add significant and primary 
  52.       functionality to the Genmix source code.
  53. 4.    You are granted a non-exclusive right to use and 
  54.       modify the Genmix source code for the sole purposes 
  55.       of designing, developing, and testing applications 
  56.       derived from the Genmix source code.
  57.  
  58. PLEASE use Genmix in your applications!  Licenses for 
  59. redistribution of derived works are available according to the following 
  60. price schedule:
  61.  
  62.     License to distribute derived works:
  63.            500 copies or less.............. $FREE
  64.            First 20,000 copies............. $500
  65.            Each additional 20,000 copies... $1000
  66.  
  67. This pricing information is subject to change without notice.  If you're a
  68. public domain or shareware author, or you feel this agreement isn't fair, 
  69. please let me know; I'll be more than happy to talk about working out 
  70. alternate arrangements.
  71.  
  72.  
  73. CONTACTING ME
  74. -------------
  75. Currently, there is no public forum for supporting Genmix.  I usually lurk
  76. on the internet at comp.os.ms-windows.programmer.multimedia, and on
  77. compu$erve at GO:GAMEDEV Windows Games.  I'll send information to
  78. those newsgroups, probably, as well as to users on the beta mailing list.
  79.  
  80. Please contact me if you have questions about Genmix, bug reports (I like
  81. those), suggestions, questions about licensing, general advice, good
  82. jokes, or any other reason to chat.
  83.  
  84. You can send email to me at:  ianm@usit.net
  85.  
  86. Snail-mail can reach me at:
  87.     Ian McLean
  88.     916 Gertrude Ave.
  89.     Knoxville TN 37920
  90.  
  91. Please contact me by email rather than telephone.
  92.  
  93.  
  94. DISTRIBUTION CONTENTS
  95. ---------------------
  96. Genmix is provided as a ZIP file, expanding to the following directory
  97. structure and files:
  98.  
  99.        /genmix/readme.txt                This file
  100.  
  101.        /genmix/bin/portwave.ini          Mixer initialization file
  102.        /genmix/bin/mixtest.exe           Mixer test program executable
  103.        /genmix/bin/mixtestd.exe          Debug mixer test program executable
  104.  
  105.        /genmix/src/genmix.c              Mixer source code
  106.        /genmix/src/port.h                Abstraction layer header
  107.        /genmix/src/portmem.c             Memory abstraction layer
  108.        /genmix/src/portwave.c            Sound hardware abstraction layer
  109.  
  110.        /genmix/tst/mixtest.c             Mixer test program source code
  111.        /genmix/tst/mixtest.rc            Test program resources
  112.        /genmix/tst/mixtest.mak           Mixer test program make file
  113.        /genmix/tst/mixtest.vcp           Some file visual c makes
  114.  
  115.  
  116. CURRENT PROBLEMS/ISSUES
  117. -----------------------
  118. Sorry!  Macintosh sound code is not included in this first beta release
  119. of Genmix.  It will be added as soon as I have time to rewrite the routines
  120. to provide a variable size ring buffer.
  121.  
  122. The file PORTWAVE.INI should be copied to your Windows directory.  This file
  123. stores the default hardware configuration data and information specific to
  124. your configuration.  PLEASE fool around with the "Hardware Config..." 
  125. options in the test program, and tune them for best results on your 
  126. configuration.  THEN, send me a copy of your PORTWAVE.INI file.  This will 
  127. let me make future releases work better, with your tweaks applied.
  128.  
  129. The best method to tweak the setting for a certain format is:
  130.        -Set number of blocks to 4
  131.        -Set block size to 16384
  132.        -Set remix to at end of block
  133.        -Set getpos to time ourselves
  134.        -Play a long sound, 5-10 seconds
  135.        -Lower block size, choosing smallest that sounds ok
  136.        -Lower number of blocks, going no less than two
  137.        -Play a short sound, <1 sec, in a loop
  138.        -Change remix to immediate
  139.        -If you get hisses or pops, note this in a bug report
  140.  
  141. If setting the block size too low crashes your system, copying the file
  142. portwave.bak over portwave.ini will undo the last configuration change
  143. you made.  If you don't undo this change, the mixer test program will crash
  144. again as soon as its loaded.
  145.  
  146. The test program is not really a very good example program.  It's sloppy,
  147. confusing, and probably buggy.
  148.  
  149. The Windows abstraction layer has several serious problem -- some of them
  150. Microsoft's fault, most the fault of individual audio driver manufacturers.
  151. I use the waveOut API to drive the sound.  The waveOut API has some flaws, 
  152. mostly because the requirements for a good quality driver aren't clearly spelt 
  153. out.  There is no function available to halt currently playing sounds without 
  154. perhaps resetting the DAC on the sound card.  Many audio manufacturers have 
  155. shipped buggy drivers with their products.  Here's some gotchas about using 
  156. the waveOut API:
  157.  
  158.     - waveOutReset can take up to 1.5 seconds to complete, and it can cause
  159.       audible clicking or popping.  This happens on SB2.0's and NEC98's.
  160.     - waveOutWrite callbacks don't occur at the correct time unless the
  161.       size of the block played is a multiple of the dma block size.  The dma
  162.       block size is 2k,4k,8k, or 16k, depending upon the device and version
  163.       of Windows.
  164.     - waveOutGetPos doesn't return an accurate count of samples played.  The
  165.       amount of inaccuracy varies from sound card to sound card.
  166.     - the sound output rate can be 5% faster or slower than stated
  167.  
  168. Due to these and several other problems, it is my opinion that
  169.  
  170.          IT IS IMPOSSIBLE TO IMPLEMENT HIGH QUALITY REAL-TIME AUDIO 
  171.          USING THE WAVEOUT API
  172.  
  173. and Microsoft should get up and do something about it.  Maybe they will --
  174. as I write this, Manhattan is still undisclosed; maybe the mysterious
  175. DirectSound API will address this problem.  I hope so!
  176.  
  177. There are several bugs still lurking in the generic mixer code.  Due to a 
  178. last minute spec change, I had to rewrite much of the data rendering code
  179. to allow for installable codecs to be added in a future release.  This
  180. introduced several new bugs into previously well-tested areas of the code.
  181. I found most of them, but I haven't had time to test the code as rigorously
  182. as I would like.  Keep your eyes peeled for 'em.
  183.  
  184. I _swear_ the mixer test program is haunted.  It seems to lock up for no
  185. reason at all on some configurations, notably Sound Blaster v2.0, when
  186. closing and reopening the mixer.  I think this might be a winmm bug, but
  187. it need further investigation.  Sound Blaster 2.0 users, please let me know
  188. how the mixer performs.  Run the test program in an environment with debug 
  189. capabilities, and set a breakpoint on portFatalError().
  190.  
  191. Many sound cards have noticeable clicks and pops when remixing.  Please let
  192. me know what your card sounds like when you send me PORTWAVE.INI information.
  193.  
  194. And, of course, many sound card drivers Just Plain Crash if you give them
  195. too complex a task.  I won't name names right now, but just be sure you
  196. have the latest version of your sound card driver, and report your driver
  197. and version along with any bug reports.
  198.  
  199. mixPause() and mixResume() aren't implemented yet.  Well, they're implemented
  200. but I haven't actually tested them to see if they work in all cases.
  201.  
  202. mixInstallCodec() and the whole on-the-fly decompression thing
  203. isn't implemented.  I've no plans to implement any codecs for release,
  204. they're won't be useful unless you want to write your own.  I _might_ be
  205. convinced to write an ADPCM codec, but only if it's not too much of a hassle.
  206. If anyone has any good ADPCM compression / decompression source, I'd really
  207. like to see it.
  208.  
  209. I've had several people suggest I come up with a better technique to fill
  210. the sound output queue than calling mixPump().  Well, I agree, something
  211. like that should be done automatically by a parallel thread.  However, I need
  212. this mixer to be able to run under Win31, and Win31 doesn't support any kind
  213. of preemptive multitasking for 32 bit programs.  Under Win32 (95 or NT), you
  214. could create a thread that does nothing but mixPump() when needed, and I
  215. _think_ there won't be any synchronization problems, but I haven't tested it
  216. yet.  Now, it _is_ possible to get a interrupt-level timer in Win32s, but
  217. waveOutWrite() should never be called from a timer interrupt (certain parts of
  218. winmm are discardable, if they're not in memory and you try to access them,
  219. you'll page fault.  Page faulting during a timer interrupt results in a 
  220. nasty crash).  Don't get hung up on Microsoft's push-pull event architecture,
  221. it's really kind of anal retentive.  See the mixer test main loop for a way
  222. to avoid having to send yourself timer messages.  CD-ROM authors, be sure
  223. to write an abstraction layer for file i/o that breaks long reads up into
  224. chunks, pumping between chunks.  I'm using mmio for file access, and haven't
  225. had a problem with the chunking slowing the transfer rate.  This will prevent
  226. dropout during long reads.
  227.  
  228. This version has not been tested on many Win32s configurations, and it hasn't
  229. been tested at all under NT.  I don't see any reason why it wouldn't work
  230. under NT, please let me know what your experiences are.
  231.  
  232.  
  233. MIXER DATA STRUCTURES
  234. ---------------------
  235.  
  236. Genmix uses only two public data structures.
  237.  
  238. The mixVol structure describes a volume setting, for left and right channels
  239. of a sound.  The mixSound structure represents a sound sample:
  240.  
  241. typedef struct tagmixSound
  242. {
  243.        mixCodecType     type;
  244.        pmem             pdata;
  245.        long             samples;
  246.        waveRate         rate;
  247.        waveBits         bits;
  248.        waveSpeak        speak;
  249.        mixVol           vol;
  250. } mixSound;
  251.  
  252. where:
  253.  
  254.        type             should be set to mixCodecPCM
  255.        pdata            is a LPSTR to the wave data
  256.        samples          counts the samples in the sound
  257.        rate             is waveRate11k, waveRate22k, or waveRate44k
  258.        bits             is either waveBits8 or waveBits16
  259.        speak            is either waveSpeakMono or waveSpeakStereo
  260.        vol              describes the volume the sound will be played at
  261.  
  262.  
  263. MIXER API
  264. ---------
  265.  
  266. The following 17 functions implement the Genmix API.  Sorry for the
  267. scant description.
  268.  
  269.  
  270. rescode        mixOpen(short numchan, waveRate rate, waveBits bits, 
  271.                     waveSpeak speak);
  272.  
  273.     Opens the sound hardware and prepares to mix sounds.  Up to (numchan)
  274.     sounds can be mixed at once.  (rate), (bits), and (speak) describe
  275.     the format of the output waveform.
  276.  
  277.  
  278. rescode        mixClose(void);
  279.  
  280.     Closes the mixer and associate sound hardware.  All playback stops.
  281.  
  282.  
  283. rescode        mixPlay(short chan, pmixSound psound);
  284.  
  285.     Plays the sound sample specified by (psound) on mixer channel (chan).
  286.     If a sound is currently playing on channel (chan), it is truncated and
  287.     (psound) starts playing immediatly.
  288.  
  289.  
  290. rescode        mixUnplay(pmem pdata);
  291.  
  292.     Stops the data (pdata) from playing, if it is currently in use by the
  293.     mixer.  This is usually called as a safeguard before disposing of
  294.     (pdata).
  295.  
  296.  
  297. rescode        mixAppend(short chan, pmixSound psound)
  298.  
  299.     Plays the sound sample (psound) on mixer channel (chan).  If a sound
  300.     is currently playing on (chan), it continues playing, and (psound) is
  301.     played after all previous sounds have finished.  If (chan) is silence,
  302.     (psound) starts playing immediatly.
  303.  
  304.  
  305. rescode        mixSilence(short chan);
  306.  
  307.     Immediatly silences channel (chan), if any sounds are playing.
  308.  
  309.  
  310. rescode        mixIsSilent(short chan);
  311.  
  312.     Returns non-zero if channel (chan) is silence, eg no sounds are playing.
  313.  
  314.  
  315. rescode        mixLoadChannel(short, pmixSound *, short);
  316.  
  317.     Not implemented yet.  Will implement theme music loops.
  318.  
  319.  
  320. rescode        mixSetVolume(short chan, pmixVol pvol);
  321.  
  322.     Sets the volume of channel (chan) to (pvol).  The output volume is
  323.     a combination of the sample volume and the volume of the channel it
  324.     is playing on.
  325.  
  326.  
  327. rescode        mixGetVolume(short chan, pmixVol pvol);
  328.  
  329.     Gets the volume of channel (chan), storing it in (pvol).
  330.  
  331.  
  332. rescode        mixIsDataPlaying(pmem pdata);
  333.  
  334.     Returns non-zero if the data (pdata) is currently in use by the mixer.
  335.  
  336.  
  337. rescode        mixPause(void);
  338.  
  339.     Not implemented yet.
  340.  
  341.  
  342. rescode        mixResume(void);
  343.  
  344.     Not implemented yet.
  345.  
  346.  
  347. rescode        mixPump(void);
  348.  
  349.     This function maintains the flow of waveform data to the sound hardware.
  350.     It must be called from the application program at least every 1/10th of
  351.     a second.
  352.  
  353.  
  354. rescode        mixVolCreate(pmixVol pvol, double dleft, double dright);
  355.  
  356.     Utility function to create a volume specifier in (pvol).  (dleft) and
  357.     (dright) specify the volume of the left and right output speakers.
  358.     0.0 is silent, 1.0 is full volume, greater than 1.0 increases the
  359.     input amplitude.
  360.  
  361.  
  362. rescode     mixVolMult(pmixVol pv1, pmixVol pv2, pmixVol pvdest);
  363.  
  364.     Utility function to combine two volume specifiers.  (pv1) is multiplied
  365.     with (pv2) and the result is placed in (pvdest)
  366.  
  367.  
  368. rescode        mixInstallCodec(pmixCodec);
  369.  
  370.     Not implemented yet.
  371.  
  372.  
  373. MIXER ARCHITECTURE
  374. ------------------
  375.  
  376. Genmix is very object oriented C code (not C++!).  To explain the different
  377. objects involved, let's trace the course of an audio sample from it's
  378. source, through the mixer, and out the speakers.  The path takes us through
  379. four different objects:
  380.  
  381. DATA SOURCE (Hungarian notation: dsrc)
  382.  
  383. A data source object is a source of waveform data.  Its primary function is
  384. to convert waveform data from one format (e.g., 22kHz, 8bit, mono) to another
  385. format (e.g., 44kHz, 16bit, stereo), a task called rendering.  A data source
  386. has the following methods:
  387.  
  388.     Render      --  render a specified number of samples to a destination
  389.                     buffer, advancing the data source stream.
  390.     Create      --  create either a source of silence or a sample stream
  391.     Destroy
  392.     Rewind      --  rewinds the data source stream
  393.     GetPos      --  gets the current data source stream pointer
  394.     Truncate    --  truncates the data source at the current position
  395.  
  396. Basically, a data source is just an abstraction for an uncompressed PCM
  397. stream.  The data source object could be tightly bound to the mixer channel
  398. without things getting too complex, but I've separated it out to allow for 
  399. easy implementation of installable codecs in the future.
  400.  
  401. MIXER CHANNEL (Hungarian notation: chan)
  402.  
  403. A mixer channel is a doubly-linked list of data sources.  It represents a
  404. temporal cross section of the mixer input.  Howzthat?  Well, in order to
  405. be able to re-render the mixer output stream, we need to keep track of the
  406. sounds we've mixed, in order to be able to remix them if the need arises.
  407. That means we need to keep track of a few seconds of source data.  This can
  408. get very complicated, for example, imaging playing five 1/4 second sample five
  409. times during a 5 second interval.  You not only have to keep track of the 
  410. samples you played, but also the amount of time _between_ the samples, in
  411. order to be able to rerender the channel stream accurately.  In order to
  412. rewind, the channel keeps a pointer to the current data source position.
  413.  
  414. So, a mixer channel supports the following methods:
  415.  
  416.     Render      -- Renders the individual data sources in the channel
  417.     Rewind      -- Rewinds the channel's current position pointer
  418.     Trim        -- Trims the channel to a certain length (from downtimewards)
  419.     Truncate    -- Truncates the channel at the current position
  420.     Add          -- Adds a new data source and the end of the channel
  421.  
  422. So, a channel is a higher level abstraction of a data source -- a 
  423. heterogeneous, temporally ordered stream
  424.  
  425. Here's what a typical mixer channel might look like:
  426.  
  427.     +------------- +   +---------------+   +--------------+
  428.     | Audio Sample |-->| Silence       |-->| AudioSample  |-->0
  429. 0<--| (dsrcSample) |<--| (dsrcSilence) |<--| (dsrcSample) |
  430.     +--------------+   +---------------+   +--------------+
  431.                                                    ^
  432.                                             CUR----+
  433.  
  434.  
  435. MIXING RING (Hungarian notation: mr)
  436.  
  437. The mixing ring is where the actual sound mixing takes place.  At this
  438. level of abstraction, we have an array of mixer channels as our input.  Each
  439. mixer channel provides data for us in the output data format.  But, we've got
  440. to mix a certain number of samples ahead, in order to ensure that enough
  441. data is queued in the hardware abstraction layer.  So, when a new sound is
  442. added with a mixPlay call, we have to do six things:
  443.  
  444.         -    Determine how many samples have been mixed but haven't been
  445.              played through the speakers yet.
  446.         -    Rewind every input channel by that amount
  447.         -    Truncate the channel we're adding too
  448.         -    Add the new sound to that channel
  449.         -    Reset the sound output hardware
  450.         -    Fill the sound output buffer with remixed samples
  451.  
  452. This is not a trivial task.  The worst part is rewinding and remixing all 
  453. the input channels.  The mixing ring reduces the overhead of rerender with
  454. each remix.
  455.  
  456. The mixing ring is an array of ring buffers.  Each ring buffer corresponds
  457. to one input channel, and holds all the samples that have been rendered for
  458. the last few seconds from that channel.  With the mixing ring, when a new
  459. sound is mixed in, we only have to rerender the channel that has changed,
  460. the other channels are stored in the ring buffer.  The ring buffer has a
  461. start, an end, and a current position.  Since all the ring buffers always
  462. have the same number of samples and current position offset, only one set
  463. of control pointers is needed.  The mixing ring supports the following
  464. methods:
  465.  
  466.     RenderAll   -    Ensure that all channels have been rendered
  467.     ReRender    -    Rewind and rerender a ring buffer
  468.     Mix         -    Mix all ring buffers and store output stream
  469.     NewSound    -    Add a new sound to a ring buffer channel
  470.  
  471.  
  472.  
  473. HARDWARE ABSTRACTION LAYER (Hungarian notation: wave)
  474.  
  475. Finally, mixed sound samples leave the mixing ring layer and are ready to
  476. be send to the sound hardware.  Everything before this point could be
  477. implemented portably and generically, but not this.  This is a platform
  478. specific task, and I've tried to come up with a simple, flexible API to
  479. describe this task.  The wave API implements a blocked ring buffer in 
  480. which blocks of samples are queued to be send to the sound hardware.
  481.  
  482. rescode        waveOpen(waveRate, waveBits, waveSpeak, int*, int*, int*);
  483.     
  484.     Opens the sound hardware at the requested rate, bits, and speakers.
  485.     This function returns the following referenced values:
  486.         blocksize        - size of a wave buffer block, in samples
  487.         playahead        - number of blocks the mixer should keep in 
  488.                            output ring
  489.         immediateremix   - flag: recommended to remix audio data?
  490.  
  491.  
  492. rescode        waveClose(void)
  493.  
  494.     Closes the sound hardware, stopping all noise.
  495.  
  496.  
  497. rescode        waveReset(void);
  498.  
  499.     Does NOT reset the sound hardware.  This sets a flag indicating whether
  500.     the next wavePlay call should empty the output buffer before playing
  501.     the indicated block.
  502.  
  503.  
  504. rescode        waveGetPlayPtr(pmem *);
  505.  
  506.     Gets a pointer to an unused audio block, so that it can be filled.  You
  507.     must have one wavePlay call for every waveGetPlayPtr call.
  508.  
  509.  
  510. rescode        wavePlay(void);
  511.  
  512.     Adds the block returned from the last waveGetPlayPtr call to the end
  513.     of the output ring buffer.  However, if waveReset was called before
  514.     calling this, the output buffer is emptied and the block should 
  515.     start playing immediately.
  516.  
  517.  
  518. rescode        waveGetSampleCount(long *)
  519.  
  520.     This returns the total number of samples that are queued for output,
  521.     but haven't gone through the speakers yet.  This count should be
  522.     accurate to the sample, if possible.
  523.  
  524.  
  525. rescode        waveSetVolume(short);
  526.  
  527.     Sets the rough output volume of the sound hardware.  The volume can
  528.     range from 0 (silent) to 7 (full).  This function is not called from 
  529.     the mixer, but should be called from the application to set a user-
  530.     controlled output level.  The advantage of this over the mixer 
  531.     volume scaling is that this is an analog scale -- you can reduce
  532.     volume without losing bits of sample resolution.
  533.  
  534. rescode        waveGetVolume(short *);
  535.  
  536.     Get the current hardware volume setting.  0 is silence, 7 is 
  537.     full volume.
  538.  
  539.  
  540. MIXER API
  541.  
  542.     The mixer API is a set of function that provide a simple, consistent
  543.     programmer interface to the different mixer objects.  They hide the
  544.     complexity of the mixer from the application layer.  See the section
  545.     "mixer api" for more information.
  546.  
  547.